using System;
using System.IO;
using System.Text;
using System.Net;
using System.Collections;
using System.Collections.Generic;

namespace TdlIcal2Appt
{
    
    class CalendarCollection
    {

        /* 
         * Utility class to fetching, storing (on disk), and providing access to ical files.
         */

        public Hashtable CalsOnDisk;
        private Hashtable CalsOnWeb;
        public string CalsDirectory;
        

        public CalendarCollection()
        {
            CalsOnDisk = new Hashtable();
            CalsOnWeb = new Hashtable();
            CalsDirectory = Properties.TdlIcal2Appt.Default.CalendarStorage.ToString();
            LoadCalendars();
        }


        private void LoadCalendars()
        {
            bool GetNextCalendar = true;
            int CalendarIndex = 0;

            // load the settings
            while (GetNextCalendar)
            {
                CalendarIndex++;
                try
                {
                    CalsOnWeb.Add( Properties.TdlIcal2Appt.Default["CalendarName" + CalendarIndex].ToString(), 
                                    Properties.TdlIcal2Appt.Default["CalendarUrl" + CalendarIndex].ToString() );
                }
                catch(Exception)
                {
                    GetNextCalendar = false;
                }
            }

            // fetch each calendar from web and store to disk
            foreach (string CalName in CalsOnWeb.Keys)
            {
                string FileCreated = string.Empty;
                try
                {
                    FileCreated = this.DownloadCalendar(CalName, CalsOnWeb[CalName].ToString());
                }
                catch (Exception ex)
                {
                    FileCreated = string.Empty;
                    Console.Error.WriteLine(ex.Message);
                }

                // replace URL with new filename
                CalsOnDisk[CalName] = FileCreated;
            }


        }

        // @@@ add web error handling
        private string DownloadCalendar(string CalendarName, string CalendarUrl)
        {

            // FROM http://www.csharp-station.com/HowTo/HttpWebFetch.aspx (slightly modified)

            // used to build entire input
            StringBuilder sb = new StringBuilder();

            // used on each read operation
            byte[] buf = new byte[8192];

            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest)
                WebRequest.Create(CalendarUrl);

            // execute the request
            HttpWebResponse response = (HttpWebResponse)
                request.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();

            string tempString = null;
            int count = 0;

            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    tempString = Encoding.ASCII.GetString(buf, 0, count);

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            // print out page source
            //Console.WriteLine(sb.ToString());

            // END FROM http://www.csharp-station.com/HowTo/HttpWebFetch.aspx (slightly modified)

            if (sb.Length == 0)
            {
                throw new ApplicationException("Could not download from \"" + CalendarUrl + "\".");
            }

            string FileToCreate = CalsDirectory + @"\" + CalendarName + ".ics";
            StreamWriter sw = new StreamWriter(FileToCreate, false);
            try
            {
                sw.Write(sb.ToString());
                sw.Close();
            }
            catch( Exception ex )
            {
                throw new ApplicationException("Could not write to \"" + FileToCreate + "\": " + ex.Message);
            }

            return FileToCreate;
        }

    }
}
